home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DESDOS.ARJ / RADLOGIN.C < prev    next >
C/C++ Source or Header  |  1989-01-30  |  4KB  |  146 lines

  1. /*
  2.  * Secure packet radio login command. The system first prompts for the
  3.  * user's name. It then generates and sends a unique "challenge" (a 64-bit
  4.  * hexadecimal integer) based on the time of day. The user encrypts
  5.  * this value using the Data Encryption Standard and his private key and
  6.  * type it back to the system. The system also encrypts the challenge
  7.  * with the user's key and compares the two. If they match, he's in.
  8.  *
  9.  * 18 December 1986 Phil Karn, KA9Q
  10.  *
  11.  * mods:
  12.  *   870318 Bdale, N3EUA     Add code to run user's .login commands.
  13.  *   870317 Bdale, N3EUA     Hacked to remove putenv() by calling execle()
  14.  *                           instead of execl().
  15.  */
  16. #include <stdio.h>
  17. #include <strings.h>
  18. #include <pwd.h>
  19. #include <utmp.h>
  20. #define    KEYFILE    "/etc/rkeys"    /* This file must be read-protected */
  21. main(argc,argv)
  22. int argc;
  23. char *argv[];
  24. {
  25.     struct passwd *pp,*getpwnam();
  26.     unsigned long t;
  27.     FILE *fp;
  28.     char name[64];
  29.     char key[8];
  30.     char work[8];
  31.     char answer[8];
  32.     char fbuf[64];
  33.     char ibuf[64];
  34.     char home[64];
  35.     char login[64];
  36.     char shell[64];
  37.     char user[64];
  38.     char *keyp;
  39.     char *cp,*tty,*ttyname();
  40.     int i,ikey[8];
  41.     struct utmp utmp;
  42.     char *ep[5];               /* we'll build an environment here */
  43.  
  44.     if((fp = fopen(KEYFILE,"r")) == NULL){
  45.         printf("Can't open key file\n");
  46.         exit(1);
  47.     }
  48.     /* Get user's name and look it up in the database */
  49.     printf("Enter login name: ");
  50.     fgets(ibuf,sizeof(ibuf),stdin);
  51.     if((cp = index(ibuf,'\n')) != NULL)
  52.         *cp = '\0';
  53.     strncpy(name,ibuf,sizeof(name));
  54.     for(;;){
  55.         fgets(fbuf,sizeof(fbuf),fp);
  56.         if(feof(fp)){
  57.             printf("No key for login name\n");
  58.             exit(2);
  59.         }
  60.         if((cp = index(fbuf,'\n')) != NULL)
  61.             *cp = '\0';
  62.         if(strncmp(name,fbuf,strlen(name)) == 0)
  63.             break;
  64.     }
  65.     fclose(fp);
  66.     /* Find the user's DES key */
  67.     if((keyp = index(fbuf,' ')) == NULL){
  68.         printf("Missing key field\n");
  69.         exit(3);
  70.     }
  71.     keyp++;
  72.     /* Initialize DES with the user's key */
  73.     sscanf(keyp,"%2x%2x%2x%2x%2x%2x%2x%2x",
  74.      &ikey[0], &ikey[1], &ikey[2], &ikey[3], &ikey[4], &ikey[5],
  75.      &ikey[6], &ikey[7]);
  76.  
  77.     for(i=0;i<8;i++)
  78.         key[i] = ikey[i];
  79.  
  80.     desinit(0);
  81.     setkey(key);
  82.  
  83.     /* Generate and send the challenge */
  84.     time(&t);
  85.     printf("Challenge: %016x\n",t);
  86.  
  87.     /* Encrypt it locally... */
  88.     for(i=0;i<4;i++)
  89.         work[i] = 0;
  90.     work[4] = t >> 24;
  91.     work[5] = t >> 16;
  92.     work[6] = t >> 8;
  93.     work[7] = t;
  94.     endes(work);
  95.     
  96.     /* ...and see if the user can do the same */
  97.     printf("Response:  ");
  98.     for(i=0;i<8;i++){
  99.         scanf("%2x",&t);
  100.         answer[i] = t;
  101.     }
  102.     printf("\n");     /* I like it better with a blank line here - bdale */
  103.     /* Compare the ciphertexts. If they match, he's in */
  104.     for(i=0; i < 8; i++){
  105.         if(work[i] != answer[i]){
  106.             printf("Wrong response\n");
  107.             exit(4);
  108.         }
  109.     }
  110.     if((pp = getpwnam(name)) == NULL){
  111.         printf("login name \"%s\" not in /etc/passwd\n",name);
  112.         exit(4);
  113.     }
  114.     if((fp = fopen(UTMP_FILE,"r+")) == NULL){
  115.         printf("can't open utmp\n");
  116.         exit(4);
  117.     }
  118.     tty = ttyname(0);
  119.     if((cp = rindex(tty,'/')) != NULL)
  120.         tty = cp + 1;
  121.     while(fread((char *)&utmp,sizeof(struct utmp),1,fp),!feof(fp)){
  122.         if(strncmp(utmp.ut_line,tty,8) == 0){
  123.             strncpy(utmp.ut_name,name,8);
  124.             fseek(fp,(long)-sizeof(struct utmp),1);
  125.             fwrite((char *)&utmp,sizeof(struct utmp),1,fp);
  126.             break;
  127.         }
  128.     }
  129.     fclose(fp);
  130.     chdir(pp->pw_dir);
  131.     setregid(pp->pw_gid,pp->pw_gid);
  132.     setreuid(pp->pw_uid,pp->pw_uid);
  133.     if(pp->pw_shell == NULL || *pp->pw_shell == '\0')
  134.         pp->pw_shell = "/bin/ksh";
  135.     sprintf(home,"HOME=%s",pp->pw_dir);
  136.     sprintf(shell,"SHELL=%s",pp->pw_shell);
  137.     sprintf(user,"USER=%s",name);
  138.     sprintf(login,"%s/.login",pp->pw_dir);
  139.     ep[0] = home;
  140.     ep[1] = shell;
  141.     ep[2] = user;
  142.     ep[3] = (char *) NULL;
  143.     execle(pp->pw_shell,"-",0,ep);
  144.     printf("Exec failed\n");
  145. }
  146.